package com.hk.core.redis.locks;

import com.hk.commons.util.SpringContextHolder;
import com.hk.commons.util.StringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;

/**
 * @author Kevin
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RedisLockRenewalStrategyHolder {

    public static final String SYSTEM_PROPERTY = "hk.core.redis.lock.renewal.strategy";

    private static RedisLockRenewalStrategy redisLockRenewalStrategy;

    private static volatile boolean beanLoading = false;

    static {
        var strategyName = System.getProperty(SYSTEM_PROPERTY);
        if (StringUtils.hasText(strategyName)) {
            try {
                redisLockRenewalStrategy = (RedisLockRenewalStrategy) Class.forName(strategyName).getConstructor().newInstance();
            } catch (Exception e) {
                ReflectionUtils.handleReflectionException(e);
            }
        } else {
            if (ClassUtils.isPresent("io.netty.util.HashedWheelTimer", null)) {
                redisLockRenewalStrategy = new NettyRedisLockRenewalStrategy();
            } else {
                redisLockRenewalStrategy = new ThreadPoolTaskScheduleRenewalStrategy();
            }
        }
    }


    private static void beanContextLoading() {
        if (!beanLoading) {
            var renewalStrategy = SpringContextHolder.getBeanIfExist(RedisLockRenewalStrategy.class)
                    .orElse(redisLockRenewalStrategy);
            if (renewalStrategy != redisLockRenewalStrategy) {
                redisLockRenewalStrategy = renewalStrategy;
            }
            beanLoading = true;
        }
    }

    public static RedisLockRenewalStrategy getRenewalStrategy() {
        beanContextLoading();
        return redisLockRenewalStrategy;
    }

    public static void shutdown() {
        beanContextLoading();
        redisLockRenewalStrategy.shutdown();
    }
}
